package org.gongliang.common.scan;


import java.lang.reflect.Method;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.gongliang.common.annotation.KLog;
import org.gongliang.common.shiro.ShiroUser;
import org.gongliang.entity.sys.Log;
import org.gongliang.kit.web.ShiroKit;
import org.gongliang.kit.web.UserAgentKit;
import org.gongliang.kit.web.WebKit;
import org.gongliang.task.TaskLog;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;

/**
 * 日志记录
 *
 * @author 龚亮
 * @date 2016年12月6日 下午8:48:30
 */
@Aspect
@Component
@Order(-1)
public class LogAop {

	public static final Logger logger = Logger.getLogger(LogAop.class);

	@Pointcut("@annotation(org.gongliang.common.annotation.KLog)")
    public void cutService() {
    }

    @Around("cutService()")
    public Object recordSysLog(ProceedingJoinPoint point) throws Throwable {

        //先执行业务
    	long beginTime = System.currentTimeMillis();
        Object result = point.proceed();
        long endTime = System.currentTimeMillis();
        Log log = new Log();
        log.setTimeConsuming((endTime-beginTime)+"");
        log.setReqOk(true);
        try {
			handle(point, log, result);
        } catch (Exception e) {
			log.setException(ExceptionUtils.getStackTrace(e));
			log.setReqOk(false);
        }finally{
    		logger.debug("日志记录:" + JSON.toJSONString(log));
			TaskLog.getSingleton().add(log);
        }
        return result;
    }

	private void handle(ProceedingJoinPoint point, Log log, Object result) throws Exception {

        //获取拦截的方法名
        Signature sig = point.getSignature();
        MethodSignature msig = null;
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }
        msig = (MethodSignature) sig;
        Object target = point.getTarget();
        Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
        String methodName = currentMethod.getName();

        ShiroUser user = ShiroKit.getLoginUser();

        //获取拦截方法的参数
        String className = point.getTarget().getClass().getName();
        Object[] params = point.getArgs();

        //获取操作名称
        KLog kLog = currentMethod.getAnnotation(KLog.class);

		logger.debug("日志记录:" + className + "." + methodName + "参数:" + params);
        
        HttpServletRequest request=WebKit.getRequest();
		log.setIp(WebKit.getIpAddr(request));
		log.setCreateDate(new java.util.Date());
		if (user != null) {
			log.setCreator(user.getId());
		}
		log.setUserAgent(UserAgentKit.getUserAgent(request).toString());
		log.setReqUrl(request.getRequestURI());
		Map<String, Object> reqParams = WebKit.getParams(request);
		if (reqParams.containsKey("password")) {
			reqParams.put("password", "******");
		}
		if (reqParams.containsKey("newPassword")) {
			reqParams.put("newPassword", "******");
		}
		log.setReqParam(JSON.toJSONString(reqParams));

		log.setReqMethod(request.getMethod());
		log.setRemark(kLog.value());
		log.setResParam(JSON.toJSONString(result));
    }
}